import 'dart:io';
import 'dart:convert';
import 'package:path_provider/path_provider.dart';
import 'package:uuid/uuid.dart';
import '../models/prompt_model.dart';
import '../models/version_model.dart';
import '../models/tag_model.dart';

/// 文件系统服务 - File System Service
/// 负责所有文件操作，包括 Prompt 的增删改查、版本管理等
class FileService {
  static const String _promptsFolder = 'prompts';
  static const String _versionsFolder = 'versions';
  static const String _tagsFolder = 'tags';
  static const String _configFolder = 'config';
  static const String _indexFile = 'index.json';
  static const String _tagsFile = 'tags.json';
  
  final Uuid _uuid = const Uuid();
  
  /// 获取应用数据目录 - Get app data directory
  Future<Directory> get _appDataDir async {
    final appDocDir = await getApplicationDocumentsDirectory();
    final promptManagerDir = Directory('${appDocDir.path}/PromptManager');
    if (!await promptManagerDir.exists()) {
      await promptManagerDir.create(recursive: true);
    }
    return promptManagerDir;
  }

  /// 获取 Prompts 目录 - Get prompts directory
  Future<Directory> get _promptsDir async {
    final appDir = await _appDataDir;
    final promptsDir = Directory('${appDir.path}/$_promptsFolder');
    if (!await promptsDir.exists()) {
      await promptsDir.create(recursive: true);
    }
    return promptsDir;
  }

  /// 获取版本目录 - Get versions directory
  Future<Directory> get _versionsDir async {
    final appDir = await _appDataDir;
    final versionsDir = Directory('${appDir.path}/$_versionsFolder');
    if (!await versionsDir.exists()) {
      await versionsDir.create(recursive: true);
    }
    return versionsDir;
  }

  /// 获取标签目录 - Get tags directory
  Future<Directory> get _tagsDir async {
    final appDir = await _appDataDir;
    final tagsDir = Directory('${appDir.path}/$_tagsFolder');
    if (!await tagsDir.exists()) {
      await tagsDir.create(recursive: true);
    }
    return tagsDir;
  }

  /// 获取配置目录 - Get config directory
  Future<Directory> get _configDir async {
    final appDir = await _appDataDir;
    final configDir = Directory('${appDir.path}/$_configFolder');
    if (!await configDir.exists()) {
      await configDir.create(recursive: true);
    }
    return configDir;
  }

  /// 初始化文件系统 - Initialize file system
  Future<void> initialize() async {
    await _appDataDir;
    await _promptsDir;
    await _versionsDir;
    await _tagsDir;
    await _configDir;
    
    // 创建索引文件 - Create index file
    await _ensureIndexFile();
    await _ensureTagsFile();
  }

  /// 确保索引文件存在 - Ensure index file exists
  Future<void> _ensureIndexFile() async {
    final configDir = await _configDir;
    final indexFile = File('${configDir.path}/$_indexFile');
    
    if (!await indexFile.exists()) {
      final initialIndex = {
        'prompts': <String, dynamic>{},
        'lastUpdated': DateTime.now().toIso8601String(),
        'version': '1.0.0',
      };
      await indexFile.writeAsString(jsonEncode(initialIndex));
    }
  }

  /// 确保标签文件存在 - Ensure tags file exists
  Future<void> _ensureTagsFile() async {
    final tagsDir = await _tagsDir;
    final tagsFile = File('${tagsDir.path}/$_tagsFile');
    
    if (!await tagsFile.exists()) {
      final initialTags = <String, dynamic>{};
      await tagsFile.writeAsString(jsonEncode(initialTags));
    }
  }

  /// 读取索引文件 - Read index file
  Future<Map<String, dynamic>> _readIndex() async {
    final configDir = await _configDir;
    final indexFile = File('${configDir.path}/$_indexFile');
    
    if (await indexFile.exists()) {
      final content = await indexFile.readAsString();
      return jsonDecode(content) as Map<String, dynamic>;
    }
    
    return {
      'prompts': <String, dynamic>{},
      'lastUpdated': DateTime.now().toIso8601String(),
      'version': '1.0.0',
    };
  }

  /// 写入索引文件 - Write index file
  Future<void> _writeIndex(Map<String, dynamic> index) async {
    final configDir = await _configDir;
    final indexFile = File('${configDir.path}/$_indexFile');
    
    index['lastUpdated'] = DateTime.now().toIso8601String();
    await indexFile.writeAsString(jsonEncode(index));
  }

  /// 创建新的 Prompt - Create new prompt
  Future<PromptModel> createPrompt({
    required String title,
    required String content,
    List<String> tags = const [],
    String category = '',
    String description = '',
    String fileFormat = 'md',
    Map<String, dynamic> metadata = const {},
  }) async {
    final promptId = _uuid.v4();
    final now = DateTime.now();
    
    // 创建 Prompt 目录 - Create prompt directory
    final promptsDir = await _promptsDir;
    final promptDir = Directory('${promptsDir.path}/$promptId');
    await promptDir.create(recursive: true);
    
    // 创建 Prompt 文件 - Create prompt file
    final prompt = PromptModel(
      id: promptId,
      title: title,
      content: content,
      tags: tags,
      category: category,
      description: description,
      createdAt: now,
      lastModified: now,
      fileFormat: fileFormat,
      metadata: metadata,
      version: 1,
      filePath: '${promptDir.path}/content${_getFileExtension(fileFormat)}',
    );
    
    // 写入内容文件 - Write content file
    await _writeContentFile(prompt);
    
    // 写入元数据文件 - Write metadata file
    await _writeMetadataFile(prompt);
    
    // 创建初始版本 - Create initial version
    await _createVersion(prompt, '初始版本');
    
    // 更新索引 - Update index
    await _updateIndex(prompt);
    
    // 更新标签使用计数 - Update tag usage count
    await _updateTagsUsage(tags, increment: true);
    
    return prompt;
  }

  /// 获取文件扩展名 - Get file extension
  String _getFileExtension(String fileFormat) {
    switch (fileFormat.toLowerCase()) {
      case 'markdown':
      case 'md':
        return '.md';
      case 'text':
      case 'txt':
        return '.txt';
      case 'word':
      case 'doc':
      case 'docx':
        return '.docx';
      case 'pdf':
        return '.pdf';
      default:
        return '.md';
    }
  }

  /// 写入内容文件 - Write content file
  Future<void> _writeContentFile(PromptModel prompt) async {
    final contentFile = File(prompt.filePath);
    await contentFile.writeAsString(prompt.content);
  }

  /// 写入元数据文件 - Write metadata file
  Future<void> _writeMetadataFile(PromptModel prompt) async {
    final promptDir = Directory(prompt.filePath).parent;
    final metadataFile = File('${promptDir.path}/metadata.json');
    await metadataFile.writeAsString(jsonEncode(prompt.toJson()));
  }

  /// 创建版本 - Create version
  Future<VersionModel> _createVersion(PromptModel prompt, String changeLog) async {
    final versionId = _uuid.v4();
    final versionsDir = await _versionsDir;
    
    // 创建版本目录 - Create version directory
    final versionDir = Directory('${versionsDir.path}/${prompt.id}');
    if (!await versionDir.exists()) {
      await versionDir.create(recursive: true);
    }
    
    final version = VersionModel(
      id: versionId,
      promptId: prompt.id,
      versionNumber: prompt.version,
      title: prompt.title,
      content: prompt.content,
      tags: prompt.tags,
      category: prompt.category,
      description: prompt.description,
      createdAt: DateTime.now(),
      changeLog: changeLog,
      filePath: '${versionDir.path}/v${prompt.version}${_getFileExtension(prompt.fileFormat)}',
    );
    
    // 写入版本文件 - Write version file
    final versionFile = File(version.filePath);
    await versionFile.writeAsString(version.content);
    
    // 写入版本元数据 - Write version metadata
    final versionMetadataFile = File('${versionDir.path}/v${prompt.version}_metadata.json');
    await versionMetadataFile.writeAsString(jsonEncode(version.toJson()));
    
    return version;
  }

  /// 更新索引 - Update index
  Future<void> _updateIndex(PromptModel prompt) async {
    final index = await _readIndex();
    final prompts = index['prompts'] as Map<String, dynamic>;
    
    prompts[prompt.id] = {
      'id': prompt.id,
      'title': prompt.title,
      'category': prompt.category,
      'tags': prompt.tags,
      'createdAt': prompt.createdAt.toIso8601String(),
      'lastModified': prompt.lastModified.toIso8601String(),
      'fileFormat': prompt.fileFormat,
      'version': prompt.version,
      'filePath': prompt.filePath,
    };
    
    await _writeIndex(index);
  }

  /// 更新标签使用计数 - Update tags usage count
  Future<void> _updateTagsUsage(List<String> tags, {required bool increment}) async {
    if (tags.isEmpty) return;
    
    final tagsDir = await _tagsDir;
    final tagsFile = File('${tagsDir.path}/$_tagsFile');
    
    Map<String, dynamic> tagsData = {};
    if (await tagsFile.exists()) {
      final content = await tagsFile.readAsString();
      tagsData = jsonDecode(content) as Map<String, dynamic>;
    }
    
    for (String tagName in tags) {
      if (tagsData.containsKey(tagName)) {
        final tagModel = TagModel.fromJson(tagsData[tagName]);
        final updatedTag = increment 
            ? tagModel.incrementUsage() 
            : tagModel.decrementUsage();
        tagsData[tagName] = updatedTag.toJson();
      } else if (increment) {
        // 创建新标签 - Create new tag
        final newTag = TagModel(
          id: _uuid.v4(),
          name: tagName,
          createdAt: DateTime.now(),
          usageCount: 1,
        );
        tagsData[tagName] = newTag.toJson();
      }
    }
    
    await tagsFile.writeAsString(jsonEncode(tagsData));
  }

  /// 获取所有 Prompt - Get all prompts
  Future<List<PromptModel>> getAllPrompts() async {
    final index = await _readIndex();
    final prompts = index['prompts'] as Map<String, dynamic>;
    
    final List<PromptModel> promptList = [];
    
    for (String promptId in prompts.keys) {
      try {
        final prompt = await getPrompt(promptId);
        if (prompt != null) {
          promptList.add(prompt);
        }
      } catch (e) {
        // print('Error loading prompt $promptId: $e');
      }
    }
    
    return promptList;
  }

  /// 获取单个 Prompt - Get single prompt
  Future<PromptModel?> getPrompt(String promptId) async {
    try {
      final promptsDir = await _promptsDir;
      final promptDir = Directory('${promptsDir.path}/$promptId');
      
      if (!await promptDir.exists()) return null;
      
      final metadataFile = File('${promptDir.path}/metadata.json');
      if (!await metadataFile.exists()) return null;
      
      final metadataContent = await metadataFile.readAsString();
      final metadata = jsonDecode(metadataContent) as Map<String, dynamic>;
      
      final prompt = PromptModel.fromJson(metadata);
      
      // 读取内容文件 - Read content file
      final contentFile = File(prompt.filePath);
      if (await contentFile.exists()) {
        final content = await contentFile.readAsString();
        // 创建新的 PromptModel 实例，包含内容 - Create new PromptModel instance with content
        return PromptModel(
          id: prompt.id,
          title: prompt.title,
          content: content,
          tags: prompt.tags,
          category: prompt.category,
          description: prompt.description,
          createdAt: prompt.createdAt,
          lastModified: prompt.lastModified,
          version: prompt.version,
          filePath: prompt.filePath,
          fileFormat: prompt.fileFormat,
          metadata: prompt.metadata,
          usageCount: prompt.usageCount,
          templateVariables: prompt.templateVariables,
        );
      }
      
      return prompt;
    } catch (e) {
      // print('Error getting prompt $promptId: $e');
      return null;
    }
  }

  /// 更新 Prompt - Update prompt
  Future<PromptModel> updatePrompt(
    String promptId, {
    String? title,
    String? content,
    List<String>? tags,
    String? category,
    String? description,
    String? fileFormat,
    Map<String, dynamic>? metadata,
    String changeLog = '',
  }) async {
    final existingPrompt = await getPrompt(promptId);
    if (existingPrompt == null) {
      throw Exception('Prompt not found: $promptId');
    }
    
    // 更新标签使用计数 - Update tag usage count
    if (tags != null) {
      await _updateTagsUsage(existingPrompt.tags, increment: false);
      await _updateTagsUsage(tags, increment: true);
    }
    
    // 创建新的 PromptModel 实例，替换 copyWith - Create new PromptModel instance instead of copyWith
    final updatedPrompt = PromptModel(
      id: existingPrompt.id,
      title: title ?? existingPrompt.title,
      content: content ?? existingPrompt.content,
      tags: tags ?? existingPrompt.tags,
      category: category ?? existingPrompt.category,
      description: description ?? existingPrompt.description,
      createdAt: existingPrompt.createdAt,
      lastModified: DateTime.now(),
      version: existingPrompt.version + 1,
      filePath: existingPrompt.filePath,
      fileFormat: fileFormat ?? existingPrompt.fileFormat,
      metadata: metadata ?? existingPrompt.metadata,
      usageCount: existingPrompt.usageCount,
      templateVariables: existingPrompt.templateVariables,
    );
    
    // 写入更新的文件 - Write updated files
    await _writeContentFile(updatedPrompt);
    await _writeMetadataFile(updatedPrompt);
    
    // 创建新版本 - Create new version
    await _createVersion(updatedPrompt, changeLog.isEmpty ? '更新内容' : changeLog);
    
    // 更新索引 - Update index
    await _updateIndex(updatedPrompt);
    
    return updatedPrompt;
  }

  /// 删除 Prompt - Delete prompt
  Future<void> deletePrompt(String promptId) async {
    final prompt = await getPrompt(promptId);
    if (prompt == null) return;
    
    // 更新标签使用计数 - Update tag usage count
    await _updateTagsUsage(prompt.tags, increment: false);
    
    // 删除 Prompt 目录 - Delete prompt directory
    final promptsDir = await _promptsDir;
    final promptDir = Directory('${promptsDir.path}/$promptId');
    if (await promptDir.exists()) {
      await promptDir.delete(recursive: true);
    }
    
    // 删除版本目录 - Delete versions directory
    final versionsDir = await _versionsDir;
    final versionDir = Directory('${versionsDir.path}/$promptId');
    if (await versionDir.exists()) {
      await versionDir.delete(recursive: true);
    }
    
    // 更新索引 - Update index
    final index = await _readIndex();
    final prompts = index['prompts'] as Map<String, dynamic>;
    prompts.remove(promptId);
    await _writeIndex(index);
  }

  /// 复制 Prompt - Duplicate prompt
  Future<PromptModel> duplicatePrompt(String promptId) async {
    final originalPrompt = await getPrompt(promptId);
    if (originalPrompt == null) {
      throw Exception('Prompt not found: $promptId');
    }
    
    return await createPrompt(
      title: '${originalPrompt.title} (副本)',
      content: originalPrompt.content,
      tags: originalPrompt.tags,
      category: originalPrompt.category,
      description: originalPrompt.description,
      fileFormat: originalPrompt.fileFormat,
      metadata: originalPrompt.metadata,
    );
  }

  /// 获取 Prompt 的所有版本 - Get all versions of a prompt
  Future<List<VersionModel>> getPromptVersions(String promptId) async {
    final versionsDir = await _versionsDir;
    final versionDir = Directory('${versionsDir.path}/$promptId');
    
    if (!await versionDir.exists()) return [];
    
    final List<VersionModel> versions = [];
    
    await for (FileSystemEntity entity in versionDir.list()) {
      if (entity is File && entity.path.endsWith('_metadata.json')) {
        try {
          final content = await entity.readAsString();
          final versionData = jsonDecode(content) as Map<String, dynamic>;
          final version = VersionModel.fromJson(versionData);
          
          // 读取版本内容 - Read version content
          final contentFile = File(version.filePath);
          if (await contentFile.exists()) {
            final versionContent = await contentFile.readAsString();
            // 创建新的 VersionModel 实例，包含内容 - Create new VersionModel instance with content
            final versionWithContent = VersionModel(
              id: version.id,
              promptId: version.promptId,
              versionNumber: version.versionNumber,
              title: version.title,
              content: versionContent,
              tags: version.tags,
              category: version.category,
              description: version.description,
              createdAt: version.createdAt,
              changeLog: version.changeLog,
              filePath: version.filePath,
              metadata: version.metadata,
            );
            versions.add(versionWithContent);
          } else {
            versions.add(version);
          }
        } catch (e) {
          // print('Error loading version from ${entity.path}: $e');
        }
      }
    }
    
    // 按版本号排序 - Sort by version number
    versions.sort((a, b) => b.versionNumber.compareTo(a.versionNumber));
    
    return versions;
  }

  /// 回滚到指定版本 - Rollback to specific version
  Future<PromptModel> rollbackToVersion(String promptId, int versionNumber) async {
    final versions = await getPromptVersions(promptId);
    final targetVersion = versions.firstWhere(
      (v) => v.versionNumber == versionNumber,
      orElse: () => throw Exception('Version $versionNumber not found'),
    );
    
    return await updatePrompt(
      promptId,
      title: targetVersion.title,
      content: targetVersion.content,
      tags: targetVersion.tags,
      category: targetVersion.category,
      description: targetVersion.description,
      changeLog: '回滚到版本 $versionNumber',
    );
  }

  /// 导出 Prompts - Export prompts
  Future<void> exportPrompts(List<PromptModel> prompts) async {
    // 这里可以实现导出功能，比如导出为 ZIP 文件
    // Implementation for exporting prompts to ZIP file
    throw UnimplementedError('Export functionality not implemented yet');
  }

  /// 导入 Prompts - Import prompts
  Future<List<PromptModel>> importPrompts(String filePath) async {
    // 这里可以实现导入功能
    // Implementation for importing prompts from file
    throw UnimplementedError('Import functionality not implemented yet');
  }

  /// 获取所有标签 - Get all tags
  Future<List<TagModel>> getAllTags() async {
    final tagsDir = await _tagsDir;
    final tagsFile = File('${tagsDir.path}/$_tagsFile');
    
    if (!await tagsFile.exists()) return [];
    
    final content = await tagsFile.readAsString();
    final tagsData = jsonDecode(content) as Map<String, dynamic>;
    
    return tagsData.values
        .map((tagJson) => TagModel.fromJson(tagJson as Map<String, dynamic>))
        .toList()
      ..sort((a, b) => b.usageCount.compareTo(a.usageCount));
  }

  /// 搜索 Prompts - Search prompts
  Future<List<PromptModel>> searchPrompts({
    String? keyword,
    List<String>? tags,
    String? category,
    DateTime? startDate,
    DateTime? endDate,
  }) async {
    final allPrompts = await getAllPrompts();
    
    return allPrompts.where((prompt) {
      // 关键词搜索 - Keyword search
      if (keyword != null && keyword.isNotEmpty) {
        final searchText = '${prompt.title} ${prompt.content} ${prompt.description} ${prompt.tags.join(' ')}'.toLowerCase();
        if (!searchText.contains(keyword.toLowerCase())) return false;
      }
      
      // 标签筛选 - Tag filter
      if (tags != null && tags.isNotEmpty) {
        if (!tags.every((tag) => prompt.tags.contains(tag))) return false;
      }
      
      // 分类筛选 - Category filter
      if (category != null && category.isNotEmpty) {
        if (prompt.category != category) return false;
      }
      
      // 日期范围筛选 - Date range filter
      if (startDate != null && prompt.createdAt.isBefore(startDate)) return false;
      if (endDate != null && prompt.createdAt.isAfter(endDate)) return false;
      
      return true;
    }).toList();
  }
}